﻿//AcademicPlanner - course registration planning web app.
//Copyright (C) 2009  Boubacar Diallo

//This program is free software; you can redistribute it and/or
//modify it under the terms of the GNU General Public License
//as published by the Free Software Foundation; either version 2
//of the License, or (at your option) any later version.

//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//GNU General Public License for more details.

//You should have received a copy of the GNU General Public License
//along with this program; if not, write to the Free Software
//Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace AcademicPlanner.Data.Entities
{
	/// <summary>
	/// AcademicPlanEntity represents the data aspect of a domain layer's <c>AcademicPlan</c>.
	/// </summary>
	/// <since>1.0</since>
    public class AcademicPlanEntity : Entity
    {
		IList<CourseEntity> courseEntities;

		IList<AcademicScheduleEntity> scheduleEntities;

		/// <summary>
		/// Gets or sets the unit of credit for courses under this AcademicPlanEntity.
		/// </summary>
		/// <since>1.0</since>
		public virtual double Credit_Unit { get; set; }

		/// <summary>
		/// Gets or sets the list of <c>CourseDivisionEntity</c>s under this AcademicPlanEntity.
		/// </summary>
		/// <since>1.0</since>
		public virtual IList<CourseDivisionEntity> DivisionEntities { get; set; }

		/// <summary>
		/// Gets or sets the list of <c>AcademicTermEntity</c>s under this AcademicPlanEntity.
		/// </summary>
		/// <since>1.0</since>
		public virtual IList<AcademicTermEntity> TermEntities { get; set; }

		/// <summary>
		/// Gets or sets the list of <c>ProgramEntity</c>s under this AcademicPlanEntity.
		/// </summary>
		/// <since>1.0</since>
		public virtual IList<ProgramEntity> ProgramEntities { get; set; }

		/// <summary>
		/// Gets the list of <c>AcademicScheduleEntity</c>s under this AcademicPlanEntity.
		/// </summary>
		/// <remarks>
		/// It is all <c>AcademicScheduleEntity</c>s of <c>ProgramEntity</c>s under 
		/// this AcademicPlanEntity. They are retrieved by 
		/// <see cref="M:AcademicPlanner.Data.Repositories.AcademicScheduleEntityRepository.FindForAcademicPlanEntity"/>.
		/// </remarks>
		/// <since>1.0</since>
		public virtual IList<AcademicScheduleEntity> ScheduleEntities
		{
			get
			{
				if (scheduleEntities == null)
					ResetScheduleEntities();
				return scheduleEntities;
			}
		}

		/// <summary>
		/// Gets the list of <c>CourseEntity</c>s under this AcademicPlanEntity.
		/// </summary>
		/// <remarks>
		/// It is the combination of all <c>CourseEntity</c>s of all <c>CourseCategoryEntity</c>s
		/// of all <c>CourseDivisionEntity</c>s under this AcademicPlanEntity. They are retrieved
		/// by <see cref="M:AcademicPlanner.Data.Repositories.CourseEntityRepository.FindForAcademicPlanEntity"/>.
		/// </remarks>
		/// <since>1.0</since>
		public virtual IList<CourseEntity> CourseEntities 
		{ 
			get
			{
				if (courseEntities == null)
					ResetCourseEntities();
				return courseEntities;
			}
		}


		/// <summary>
		/// Sets default values for this AcademicPlanEntity's properites.
		/// </summary>
		/// <remarks>
		/// <c>Credit_Unit</c> is set to <c>0.5</c>.
		/// <c>CourseDivisionEntitiesode</c>, <c>AcademicTermEntities</c>,
		/// <c>ProgramEntities</c> are set to empty lists.
		/// </remarks>
		/// <since>1.0</since>
		public override void SetDefaults()
		{
			base.SetDefaults();
			Credit_Unit = 0.5;
			DivisionEntities = new List<CourseDivisionEntity>();
			TermEntities = new List<AcademicTermEntity>();
			ProgramEntities = new List<ProgramEntity>();
			scheduleEntities = new List<AcademicScheduleEntity>();
			courseEntities = new List<CourseEntity>();
		}

		/// <summary>
		/// Resets this AcademicPlanEntity's <c>CourseEntities</c> to a
		/// new list retrieved from the storage by 
		/// <see cref="M:AcademicPlanner.Data.Repositories.CourseEntityRepository.FindForAcademicPlanEntity"/>
		/// </summary>
		/// <since>1.0</since>
		protected internal virtual void ResetCourseEntities()
		{
			courseEntities = DSAS.CourseEntityRepo.FindForAcademicPlanEntity(Id);
		}

		/// <summary>
		/// Resets this AcademicPlanEntity's <c>ScheduleEntities</c> to a
		/// new list retrieved from the storage by 
		/// <see cref="M:AcademicPlanner.Data.Repositories.AcademicScheduleEntityRepository.FindForAcademicPlanEntity"/>
		/// </summary>
		/// <since>1.0</since>
		protected internal virtual void ResetScheduleEntities()
		{
			scheduleEntities = DSAS.AcademicScheduleEntityRepo.FindForAcademicPlanEntity(Id);
		}

		/// <summary>
		/// Adds a <c>AcademicTermEntity</c> to this AcademicPlanEntity's <c>TermEntities</c>.
		/// </summary>
		/// <param name="pEntity">The <c>AcademicTermEntity</c> to add.</param>
		/// <since>1.0</since>
		public virtual void AddTermEntity(AcademicTermEntity pEntity)
		{
			pEntity.PlanEntity = this;
			TermEntities.Add(pEntity);
		}

		/// <summary>
		/// Adds a <c>CourseDivisionEntity</c> to this AcademicPlanEntity's <c>DivisionEntities</c>.
		/// </summary>
		/// <param name="pEntity">The <c>CourseDivisionEntity</c> to add.</param>
		/// <since>1.0</since>
		public virtual void AddDivisionEntity(CourseDivisionEntity pEntity)
		{
			pEntity.PlanEntity = this;
			DivisionEntities.Add(pEntity);
		}

		/// <summary>
		/// Adds a <c>ProgramEntity</c> to this AcademicPlanEntity's <c>ProgramEntities</c>.
		/// </summary>
		/// <param name="pEntity">The <c>ProgramEntity</c> to add.</param>
		/// <since>1.0</since>
		public virtual void AddProgramEntity(ProgramEntity pEntity)
		{
			pEntity.PlanEntity = this;
			ProgramEntities.Add(pEntity);
		}

		/// <summary>
		/// Adds a <c>AcademicScheduleEntity</c> to this AcademicPlanEntity's <c>ScheduleEntities</c>.
		/// </summary>
		/// <param name="pEntity">The <c>AcademicScheduleEntity</c> to add.</param>
		/// <since>1.0</since>
		public virtual void AddScheduleEntity(AcademicScheduleEntity pEntity)
		{
			scheduleEntities.Add(pEntity);
		}

		/// <summary>
		/// Adds a <c>CourseEntity</c> to this AcademicPlanEntity's <c>CourseEntities</c>.
		/// </summary>
		/// <param name="pEntity">The <c>CourseEntity</c> to add.</param>
		/// <since>1.0</since>
		public virtual void AddCourseEntity(CourseEntity pEntity)
		{
			courseEntities.Add(pEntity);
		}
    }
}
